package com.acme.bankapp.email;

/**
 * Class is used to create a service that sends email messages
 * from a separate thread.
 *
 * @author S.Zhidkov
 */
public class EmailService implements Runnable{

    private static final String MESSAGE_EMAIL_SENT = "Email was sent succefully!";

    private Queue emailQueue = new Queue();

    private boolean canRun;

    /**
     * Each EmailService instance creates execution thread, which
     *  sends email messages, if they are present in the email queue.
     */
    public EmailService() {
        canRun = true;
        Thread thread = new Thread(this);
        thread.start();
    }

    /**
     * Method adds a email message to a queue of messages to be sent as soon as possible.
     *
     * @param email
     */
    public void sendNotificationEmail(Email email) {
        synchronized (emailQueue) {
            emailQueue.add(email);
            emailQueue.notifyAll();
        }
    }

    /**
     * Method sends all email messages from the queue.
     *
     * @param messages
     */
    private void sendMessages(Queue messages) {
        while(!messages.isEmpty()) {
            sendMessage(messages.removeFirst());
        }
    }

    // try to send not really a real message
    private void sendMessage(Email email) {
        // emulate pause to send message
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(MESSAGE_EMAIL_SENT);
        System.out.println(email);
    }

    @Override
    public void run() {
        while (canRun) {
            synchronized (emailQueue) {
                while (emailQueue.isEmpty()) {
                    try {
                        emailQueue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                sendMessages(emailQueue);
            }
        }
    }

    /**
     * Method prohibits the addition of new email messages,
     *  sends the remaining email messages and stops the thread.
     */
    public void close() {
        canRun = false;
    }
}
